package affd.logic;

import java.util.ArrayList;
import java.util.HashMap;

import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;


/**
 * A EmailAnonymizer is a implementation of the Anonymizer
 * to anonymize email addresses.
 *
 */
public class EmailAnonymizer implements Anonymizer {
	
	public static final String MODIFICATION_CLASS_EMAIL = "email";
	
	public static final String EMAIL_MARKER = "\u0040";
	public static final String DOT_MARKER = ".";
	public static final String REPLACEMENT_WORD = "S\u00E4hk\u00F6postiosoite";
	
	private NameReplacement replacer;
	
	private HashMap<String, Token> processedEmails;
	
	public EmailAnonymizer(NameReplacement replacer) {
		this.replacer = replacer;
		
		// Create collection of the processed email addresses
		processedEmails = new HashMap<String, Token>();
	}

	/**
	 * Anonymizes email addresses.
	 * 
	 * @throws LogicException
	 */
	public void process(ArrayList<Sentence> sentences) throws LogicException {
		for(Sentence sentence : sentences) {
			ArrayList<Token> tokens = sentence.getTokens();
			for(Token token : tokens) {
				// Check if valid email address
				if(isEmailAddress(token.getOriginal())) {
					// Anonymize token
					anonymize(token);
				}
			}
		}
	}
	
	/**
	 * Checks if the specified token is an valid email address.
	 * 
	 * @param token Token to be tested.
	 * @return True if the token is valid email address otherwise false.
	 */
	public boolean isEmailAddress(String token) {
		if(token.contains(EMAIL_MARKER) && token.contains(DOT_MARKER)) {
			// Try to split address
			String[] splitted = token.split(EMAIL_MARKER);
			
			if(splitted.length == 2 && !splitted[0].isEmpty() && !splitted[1].isEmpty()) {
				// Check for valid domain
				try {
					InternetAddress emailAddress = new InternetAddress(token);
					
					// Token is valid email address
					return true;
				} catch (AddressException ex){
					return false;
				}
			}
		}
		
		return false;
	}

	/**
	 * Anonymizes the specified token as email address.
	 */
	public void anonymize(Token token) {
		if(replacer != null) {
			// Try find existing email
			Token processed = processedEmails.get(token.getOriginal());
			if(processed != null && processed.getTag() != null) {
				// Get group id
				String groupId = processed.getTag().getAttribute(Token.HTML_ATTRIBUTE_GROUP_ID);
				
				token.modifyContent(processed.getContent(), MODIFICATION_CLASS_EMAIL, groupId);
			} else {
				// Create group id
				String groupId = Token.generateGroupId();
				
				token.modifyContent(replacer.getEmailReplacement(), MODIFICATION_CLASS_EMAIL, groupId);
				
				// Add to processed
				processedEmails.put(token.getOriginal(), token);
			}
		}
	}
}
